package cn.rocksolid.sport.security.service.impl;

import cn.rocksolid.sport.common.C;
import cn.rocksolid.sport.common.utils.QwUtils;
import cn.rocksolid.sport.security.dao.RoleDao;
import cn.rocksolid.sport.security.dao.RoleMenuDao;
import cn.rocksolid.sport.security.dao.UserRoleDao;
import cn.rocksolid.sport.security.entity.RoleEntity;
import cn.rocksolid.sport.security.entity.RoleMenuEntity;
import cn.rocksolid.sport.security.entity.UserRoleEntity;
import cn.rocksolid.sport.security.service.RoleService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * System Role service implementation
 *
 * @author Axl Zhao
 * @email axl.zhao@163.com
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleDao, RoleEntity> implements RoleService {

  private final UserRoleDao userRoleDao;

  private final RoleMenuDao roleMenuDao;

  @Autowired
  public RoleServiceImpl(final UserRoleDao userRoleDao, final RoleMenuDao roleMenuDao) {
    this.userRoleDao = userRoleDao;
    this.roleMenuDao = roleMenuDao;
  }

  @Override
  public IPage<RoleEntity> paging(final IPage<RoleEntity> page, final JSONObject cond) {
    return this.page(page, QwUtils.fuzzy(cond, C.TITLE.f, C.REMARK.f));
  }

  @Override
  public RoleEntity get(final String id) {
    RoleEntity roleEntity = this.getById(id);
    if (null != roleEntity) {
      roleEntity.setMenuIds(
              CollectionUtils.collect(roleMenuDao.selectList(new QueryWrapper<RoleMenuEntity>().eq(C.ROLE_ID.f, id)),
                      RoleMenuEntity::getMenuId));
    }
    return roleEntity;
  }

  @Override
  public void create(final RoleEntity roleEntity) {
    this.save(roleEntity);
    this.refreshMenus(roleEntity.getId(), roleEntity.getMenuIds());
  }

  @Override
  public void modify(final RoleEntity roleEntity) {
    this.updateById(roleEntity);
    this.refreshMenus(roleEntity.getId(), roleEntity.getMenuIds());
  }

  @Override
  public void removes(final Collection<String> ids) {
    if (CollectionUtils.isNotEmpty(ids)) {
      this.removeByIds(ids);
      userRoleDao.delete(new UpdateWrapper<UserRoleEntity>().in(C.ROLE_ID.f, ids));
      roleMenuDao.delete(new UpdateWrapper<RoleMenuEntity>().in(C.ROLE_ID.f, ids));
    }
  }

  @Override
  public void refreshMenus(final String id, final Collection<String> menuIds) {
    // Delete user and role relations
    roleMenuDao.delete(new UpdateWrapper<RoleMenuEntity>().eq(C.ROLE_ID.f, id));
    if (CollectionUtils.isEmpty(menuIds)) {
      return;
    }
    // Save new relations between the menu and role
    for (String mid : menuIds) {
      RoleMenuEntity roleMenuEntity = new RoleMenuEntity();
      roleMenuEntity.setRoleId(id);
      roleMenuEntity.setMenuId(mid);
      roleMenuDao.insert(roleMenuEntity);
    }
  }
}
